'''
携程
携程：是一种用户态的轻量级线程，也称为微线程。协程的调度完全由用户控制，不需要操作系统的参与。协程的特点是：
1. 协程是一种用户态的轻量级线程，也称为微线程。
2. 协程的调度完全由用户控制，不需要操作系统的参与。
3. 携程在单线程中执行，不需要多线程的切换开销，所以效率非常高。


使用协程的优点有：
1.  高效: 协程可以在单线程中实现并发执行，避免了线程切换的开销，提高了程序的效率。
2.  轻量级: 协程比线程更轻量级，创建和切换协程的开销比线程小得多。
3.  易于使用: 协程的使用比线程更容易，协程可以通过 `yield` 关键字来实现协程的切换。
4.  避免死锁: 协程可以避免死锁的问题，因为协程是单线程的，不存在线程之间的竞争。
5.  提高响应性: 协程可以提高程序的响应性，因为协程可以在单线程中实现并发执行，避免了线程阻塞的问题。
6.  简化代码: 协程可以简化代码，因为协程可以通过 `yield` 关键字来实现协程的切换，避免了线程之间的通信问题。
7.  提高可读性: 协程可以提高代码的可读性，因为协程的代码结构更清晰，易于理解。
8.  支持异步编程: 协程支持异步编程，协程可以通过 `yield` 关键字来实现异步编程，提高了程序的效率。
总的来说，使用协程可以提高程序的效率、轻量级、易于使用、避免死锁、提高响应性、简化代码、提高可读性和支持异步编程。


协程的实现方式：
1. 生成器：yield
2. asyncio：async和await
3. tornado：IOLoop
4. twisted：Deferred
5. gevent：gevent
6. 第三方库：tornado、twisted、gevent、asyncio

必须要 await 关键字吗？
不一定，但是如果没有 await 关键字，那么这个函数就不是一个协程函数，而是一个普通的函数。
如果没有 await 关键字，那么这个函数就不会被协程调度器调度，也就不会被协程执行。

只用 async 关键字，也可以创建一个协程函数，但是这个函数不会被协程调度器调度，也就不会被协程执行。
如果要让这个函数被协程调度器调度，那么必须要使用 await 关键字。

async 和 await 关键字要么一起使用，要么都不使用？必须要一起使用，否则会报错。

async 和 await 关键字的作用？
async 关键字用于定义一个协程函数，await 关键字用于等待一个协程对象。
当一个协程函数被调用时，它会返回一个协程对象。当一个协程对象被等待时，协程调度器会将这个协程对象加入到事件循环中，等待它被调度。
当一个协程对象被调度时，它会执行它的代码，直到遇到 await 关键字，
然后将控制权交还给协程调度器，等待 await 关键字后面的协程对象执行完毕。
当 await 关键字后面的协程对象执行完毕时，控制权会交还给被等待的协程对象，
然后继续执行后面的代码。

'''

import asyncio

async def fetch(url):
    print(f"请求 {url}")
    await asyncio.sleep(2)  # 模拟网络请求
    return f"{url} 的响应"

async def main():
    tasks = [fetch(f"url_{i}") for i in range(3)]
    results = await asyncio.gather(*tasks)  # 并发执行
    print(results)

asyncio.run(main())
